package org.springframework.beans.extend;

import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.xml.BeanDefinitionDocumentReader;
import org.springframework.beans.factory.xml.BeanDefinitionParserDelegate;
import org.springframework.beans.factory.xml.XmlReaderContext;
import org.springframework.lang.Nullable;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import static org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.BEAN_ELEMENT;

public class MyDefaultBeanDefinitionDocumentReader
		implements BeanDefinitionDocumentReader {

	private BeanDefinitionParserDelegate delegate;
	private XmlReaderContext readerContext;
	@Override
	public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) throws BeanDefinitionStoreException {
		this.readerContext=readerContext;
		Element root= doc.getDocumentElement();
		BeanDefinitionParserDelegate parent = this.delegate;
		this.delegate = createDelegate(readerContext, root, parent);
		parseBeanDefinitions(root, this.delegate);
//		BeanDefinitionRegistry registry= readerContext.getRegistry();
//		registry.registerBeanDefinition();
//		readerContext.getReader().
//				registerBeanDefinitions(doc,readerContext.getResource());
	}
	protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
		if (delegate.isDefaultNamespace(root)) {
			NodeList nl = root.getChildNodes();
			for (int i = 0; i < nl.getLength(); i++) {
				Node node = nl.item(i);
				if (node instanceof Element) {
					Element ele = (Element) node;
					if (delegate.isDefaultNamespace(ele)) {
						parseDefaultElement(ele, delegate);
					}
					else {
						delegate.parseCustomElement(ele);
					}
				}
			}
		}
		else {
			delegate.parseCustomElement(root);
		}
	}

	private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
		if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
			processBeanDefinition(ele, delegate);
		}
	}
	protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
		BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
		if (bdHolder != null) {
			bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
			// Register the final decorated instance.
			System.out.println("注册bean："+bdHolder.getBeanName());
			BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder,
					readerContext.getRegistry());

		}
	}

	protected BeanDefinitionParserDelegate createDelegate(
			XmlReaderContext readerContext, Element root, @Nullable BeanDefinitionParserDelegate parentDelegate) {

		BeanDefinitionParserDelegate delegate = new BeanDefinitionParserDelegate(readerContext);
		delegate.initDefaults(root, parentDelegate);
		return delegate;
	}
}
